package com.peaw.exception.resolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.MessageSource;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;

import com.peaw.exception.PeawException;
import com.peaw.exception.PeawRuntimeException;
import com.peaw.exception.ValidationException;
import com.peaw.util.Utils;

/**
 * <pre>
 * <b></b>
 *
 * </pre>
 *
 * @author MrLiberte
 * @version 1.0.0 [2016年4月14日]
 */
public class PeawExceptionResolver extends AbstractHandlerExceptionResolver {

	private MessageSource messageSource;
	private String defaultViewName;

	/**
	 * 默认异常码
	 */
	private static String DEFAULT_ERROR_CODE = "system.err";

	/**
	 * 默认异常信息。
	 */
	private static String DEFAULT_EXCEPTION_MESSAGE = "System error.";

	@Override
	protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

		ModelAndView modelAndView = new ModelAndView();

		String exceptionCode = null, exceptionMessage = null, exceptionViewName = null;
		if (!Utils.isNullOrEmpty(ex.getLocalizedMessage())) {
			exceptionCode = ex.getLocalizedMessage();
			if (ex instanceof ValidationException) {
				exceptionMessage = messageSource.getMessage(exceptionCode, ((ValidationException) ex).getArgs(), DEFAULT_EXCEPTION_MESSAGE, request.getLocale());
				exceptionViewName = (String) request.getAttribute("_URL");
			} else if (ex instanceof PeawException) {
				exceptionMessage = messageSource.getMessage(exceptionCode, ((PeawException) ex).getArgs(), DEFAULT_EXCEPTION_MESSAGE, request.getLocale());
			} else if (ex instanceof PeawRuntimeException) {
				exceptionMessage = messageSource.getMessage(exceptionCode, ((PeawRuntimeException) ex).getArgs(), DEFAULT_EXCEPTION_MESSAGE, request.getLocale());
			}
		}

		modelAndView.addObject("_exceptionCode", Utils.isNullOrEmpty(exceptionCode) ? DEFAULT_ERROR_CODE : exceptionCode);
		modelAndView.addObject("_exceptionMessage", exceptionMessage == null ? DEFAULT_EXCEPTION_MESSAGE : exceptionMessage);
		modelAndView.setViewName(exceptionViewName == null ? defaultViewName : exceptionViewName);

		logger.debug(modelAndView.toString());

		return modelAndView;
	}

	public MessageSource getMessageSource() {
		return messageSource;
	}
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}

	public void setDefaultViewName(String defaultViewName) {
		this.defaultViewName = defaultViewName;
	}
}
